package com.example.opengldemo.simpleGame.object;

import android.opengl.GLES30;

import com.example.opengldemo.simpleGame.MatrixState.MatrixState2D;
import com.example.opengldemo.simpleGame.SimpleShaderHandle;
import com.example.opengldemo.simpleGame.constant.Constant;
import com.example.opengldemo.util.ShaderBuffer;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import static com.example.opengldemo.simpleGame.constant.SourceConstant.*;

public class BN2DObject {
    ShaderBuffer shaderBuffer ;
    SimpleShaderHandle shaderHandle ;
    int texId;
    boolean initFlag = false;
    float x;
    float y;
    boolean isLoad = false;

    int han = 0;
    int lie = 0;
    int HZ;
    int LZ;
    int spng = 0;

    public BN2DObject(float x, float y, float picWidth, float picHeight, int texId, int programId) {
        this.x = Constant.fromScreenXToNearX(x);
        this.y = Constant.fromScreenYToNearY(y);
        this.texId = texId;
        initVertexData(picWidth, picHeight, programId);
    }

    public BN2DObject(float x, float y, float picWidth, float picHeight, int texId, int programId, int spng) {
        this.x = Constant.fromScreenXToNearX(x);
        this.y = Constant.fromScreenYToNearY(y);
        this.texId = texId;
        this.spng = spng;
        initVertexData(picWidth, picHeight, programId);
    }

    public BN2DObject(float x, float y, float width, float height, int han, int lie, int HZ, int LZ,
                      int texId, int programId) {

        this.HZ = HZ;
        this.LZ = LZ;
        this.han = han; //
        this.lie = lie; //
        isLoad = true;
        this.x = Constant.fromScreenXToNearX(x);  // x平移
        this.y = Constant.fromScreenYToNearY(y); // y平移
        this.texId = texId;
        initVertexData(width, height , programId);

    }

    public void initVertexData(float width, float height , int program) {
        shaderBuffer = new ShaderBuffer()  ;
        shaderHandle = new SimpleShaderHandle(program , false) ;

        width = Constant.fromPixSizeToNearSize(width); // 顶点位置x
        height = Constant.fromPixSizeToNearSize(height); //  顶点位置y

        float vertices[] = new float[]
                {
                        -width / 2, height / 2, 0,
                        -width / 2, -height / 2, 0,
                        width / 2, height / 2, 0,
                        width / 2, -height / 2, 0
                };
        shaderBuffer.setVertexBuffer(vertices);

        float[] texCoor = null;

        if (!isLoad) {
            texCoor = new float[]{
                    0, 0, 0, 1, 1, 0,
                    1, 1, 1, 0, 0, 1};
        } else {

            float sstep = (float) 1 / LZ;
            float tstep = (float) 1 / HZ;
            texCoor = new float[]{
                    sstep * han - sstep, tstep * lie - tstep,
                    sstep * han - sstep, tstep * lie,
                    sstep * han, tstep * lie - tstep,

                    sstep * han, tstep * lie,
                    sstep * han, tstep * lie - tstep,
                    sstep * han - sstep, tstep * lie
            };
        }
        shaderBuffer.setTexcoorBuffer(texCoor);
    }

    public void initShader() {
        shaderHandle.handleMaps("CLStep" , -3);
        shaderHandle.handleMaps("xPosition" , -3);
        shaderHandle.build() ;
    }

    public void setY(float y) {
        this.y = Constant.fromScreenYToNearY(y);
    }

    public void setX(float x) {
        this.x = Constant.fromScreenXToNearX(x);
    }

    public void drawSelf() {
        if (!initFlag) {
            initShader();
            initFlag = true;
        }


        shaderHandle.program() ;
        GLES30.glUniform1f(shaderHandle.getHandleIndex("CLStep"), step);
        GLES30.glUniform1f(shaderHandle.getHandleIndex("xPosition"), loadPosition);
        MatrixState2D.pushMatrix();
        MatrixState2D.translate(x, y, 0);
        if (spng == 1) {
            MatrixState2D.scale(step / 100, step / 100, step / 100);
            MatrixState2D.rotate(AngleSpng, 0, 0, 1);
        }
        if (spng == 2) {
            MatrixState2D.rotate(Angle2D, 0, 0, 1);
        }
        if (spng == 3) {
            MatrixState2D.rotate(AngleSpng, 0, 0, 1);
        }
        if (spng == 4) {
            MatrixState2D.scale(step / 100, step / 100, step / 100);
        }

        shaderHandle.bindMVPMaxtrixHandle(MatrixState2D.getFinalMatrix()) ;
        shaderHandle.bindVertexHandle(shaderBuffer.getVertexBuffer())  ;
        shaderHandle.bindTexCoorsHandle(shaderBuffer.getTexcoorBuffer())  ;
        shaderHandle.bindDefaultTextureHandle(texId) ;
        GLES30.glEnable(GLES30.GL_BLEND);
        GLES30.glBlendFunc(GLES30.GL_SRC_ALPHA, GLES30.GL_ONE_MINUS_SRC_ALPHA);
        shaderHandle.run(GLES30.GL_TRIANGLE_STRIP , shaderBuffer.vCount);
        MatrixState2D.popMatrix();
        GLES30.glDisable(GLES30.GL_BLEND);


    }

    public void drawSelf(float lx, float ly) {
        if (!initFlag) {
            initShader();
            initFlag = true;
        }

        shaderHandle.program() ;

        MatrixState2D.pushMatrix();
        lx = Constant.fromScreenXToNearX(lx);
        ly = Constant.fromScreenYToNearY(ly);
        MatrixState2D.translate(lx, ly, 0);
        shaderHandle.bindMVPMaxtrixHandle(MatrixState2D.getFinalMatrix()) ;
        shaderHandle.bindVertexHandle(shaderBuffer.getVertexBuffer())  ;
        shaderHandle.bindTexCoorsHandle(shaderBuffer.getTexcoorBuffer())  ;
        shaderHandle.bindDefaultTextureHandle(texId) ;
        GLES30.glEnable(GLES30.GL_BLEND);
        GLES30.glBlendFunc(GLES30.GL_SRC_ALPHA, GLES30.GL_ONE_MINUS_SRC_ALPHA);
        shaderHandle.run(GLES30.GL_TRIANGLE_STRIP , shaderBuffer.vCount);
        GLES30.glDisable(GLES30.GL_BLEND);
        MatrixState2D.popMatrix();
    }
}
